package priv.lhy.log.core;

import com.fasterxml.jackson.databind.json.JsonMapper;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.logging.log4j.ThreadContext;
import priv.lhy.log.entity.RequestInfo;
import priv.lhy.log.entity.ResponseInfo;
import priv.lhy.log.util.MethodInvocationUtil;

import java.util.Optional;

/**
 * @author : lihy
 * @date : 2021/8/5 11:34
 */
@Slf4j
public class ServiceLogAdvice implements MethodInterceptor {

    private final JsonMapper jsonMapper = new JsonMapper();

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        long start = System.currentTimeMillis();

        //若没有启动web日志，线程上下文中则没有traceId
        Optional.ofNullable(ThreadContext.get("traceId")).ifPresent(s ->
                ThreadContext.put("traceId",
                        java.util.UUID.randomUUID().toString().replaceAll("-", "").toUpperCase()));


        RequestInfo requestInfo = new RequestInfo();
        requestInfo.setClassMethod(String.format("%s.%s", invocation.getMethod().getDeclaringClass().getName(),
                invocation.getMethod().getName()));
        if (invocation.getMethod().getParameters().length > 0) {
            requestInfo.setRequestParams(jsonMapper
                    .writeValueAsString(MethodInvocationUtil.getParamsByInvocation(invocation)));
        }
        log.info("Service Request Info      : {}", requestInfo.toString());

        Object result = invocation.proceed();

        ResponseInfo responseInfo = new ResponseInfo();
        responseInfo.setClassMethod(String.format("%s.%s", invocation.getMethod().getDeclaringClass().getName(),
                invocation.getMethod().getName()));
        responseInfo.setTimeCost(System.currentTimeMillis() - start);
        responseInfo.setResult(result);
        log.info("Service Response Info      : {}", responseInfo.toString());

        return result;
    }
}
